// 文件名：configv2.cpp
// 作者：Hollson <hollson@163.com>
// 日期：2025-02-16 14:00
// 描述：解析配置文件 (不使用vector)

#include <fstream>
#include <iostream>
#include <iterator>
#include <stdexcept>
#include <string>
#include "cJSON.h"

class AppConfig {
public:
	struct RedisConfig {
		std::string host;
		int         port = 0;
	};

	struct Service {
		int         id = 0;
		std::string service;
		bool        enabled = false;
	};

	std::string name;
	int         port = 0;
	RedisConfig redis;
	Service    *services     = nullptr; // 动态分配内存
	size_t      serviceCount = 0;       // 记录服务数量

	static AppConfig parse(const std::string &filename);
	void             print() const;
	~AppConfig(); // 析构函数，用于释放动态分配的内存
};

AppConfig::~AppConfig() {
	delete[] services; // 释放动态分配的内存
}

AppConfig AppConfig::parse(const std::string &filename) {
	std::ifstream ifs(filename);
	if (!ifs) throw std::runtime_error("Cannot open file");

	std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));

	cJSON *root = cJSON_Parse(content.c_str());
	if (!root) throw std::runtime_error("Invalid JSON");

	AppConfig config;

	// 解析基础字段
	if (auto name = cJSON_GetObjectItem(root, "name")) {
		config.name = name->valuestring;
	}
	if (auto port = cJSON_GetObjectItem(root, "port")) {
		config.port = port->valueint;
	}

	// 解析redis配置
	if (auto redis = cJSON_GetObjectItem(root, "redis")) {
		if (auto host = cJSON_GetObjectItem(redis, "host")) {
			config.redis.host = host->valuestring;
		}
		if (auto port = cJSON_GetObjectItem(redis, "port")) {
			config.redis.port = port->valueint;
		}
	}

	// 解析服务数组
	if (auto services = cJSON_GetObjectItem(root, "services")) {
		if (cJSON_IsArray(services)) {
			config.serviceCount = cJSON_GetArraySize(services);
			config.services     = new Service[config.serviceCount]; // 动态分配内存

			for (size_t i = 0; i < config.serviceCount; i++) {
				cJSON  *item = cJSON_GetArrayItem(services, static_cast<int>(i));
				Service s;

				if (auto id = cJSON_GetObjectItem(item, "id")) {
					s.id = id->valueint;
				}
				if (auto service = cJSON_GetObjectItem(item, "service")) {
					s.service = service->valuestring;
				}
				if (auto enabled = cJSON_GetObjectItem(item, "enabled")) {
					s.enabled = cJSON_IsTrue(enabled);
				}

				config.services[i] = s;
			}
		}
	}

	cJSON_Delete(root);
	return config;
}

void AppConfig::print() const {
	std::cout << "Application Config:\n";
	std::cout << "Name: " << name << "\n";
	std::cout << "Port: " << port << "\n";

	std::cout << "\nRedis Config:\n";
	std::cout << "  Host: " << redis.host << "\n";
	std::cout << "  Port: " << redis.port << "\n";

	std::cout << "\nServices (" << serviceCount << "):\n";
	for (size_t i = 0; i < serviceCount; i++) {
		const auto &s = services[i];
		std::cout << "[" << i << "] ID: " << s.id << ", Service: " << s.service << ", Enabled: " << (s.enabled ? "true" : "false") << "\n";
	}
}

// 构建:
// g++ -I libs -std=c++11 -c ./src/configV2.cpp -o ./bin/config_v2.o
// g++ ./bin/config_v2.o ./bin/cJSON.o  -o ./bin/config_v2
int main() {
	try {
		auto config = AppConfig::parse("etc/config.json");
		config.print();
	} catch (const std::exception &e) {
		std::cerr << "Error: " << e.what() << std::endl;
		return 1;
	}
	return 0;
}
